
#ifndef _RECOG_INTERFACE_H__
#define _RECOG_INTERFACE_H__
#include "ingenic_mnni.h"
#include "common/common_utils.h"
#include "utils/imgproc.h"
#include "utils/postproc.h"
#include "common/common_utils.h"
#include "data_type.h"

using namespace magik::uranus;
using namespace std;


namespace Recog {
    /**
     * @brief 识别配置参数结构体
     * 包含模型路径、输入尺寸、距离阈值等识别相关配置
     */
    typedef struct {
        float dist_thres = 0.5;    ///< 特征匹配距离阈值，小于此值认为匹配成功
        std::string model_path;    ///< 模型文件路径
        int input_w = 224;         ///< 模型输入图像宽度
        int input_h = 224;         ///< 模型输入图像高度
        int size = 128;            ///< 特征向量维度大小
    }RecogConfig;

    /**
     * @brief 注册信息结构体
     * 存储已注册猫只的ID、名称和特征向量
     */
    typedef struct {
        std::string id;            ///< 猫只唯一标识ID
        std::string name;          ///< 猫只名称
        std::vector<float> feat;   ///< 猫只面部特征向量
    }RegisterInfo;

    /**
     * @brief 识别结果结构体
     * 存储猫脸识别的匹配结果
     */
    typedef struct {
        std::string id;            ///< 匹配到的猫只ID
        std::string name;          ///< 匹配到的猫只名称
        bool is_match;             ///< 是否匹配成功
        float distance;            ///< 与注册特征的距离值
    }RecognizeInfo;

    /**
     * @brief 猫脸识别接口类
     * 提供模型加载、猫只注册、特征提取和识别匹配等功能
     */
    class RecogInterface {
        private:
            RecogConfig  recog_config;  ///< 识别配置参数
            magik::uranus::Network* model=nullptr;  ///< 推理网络指针

            /**
             * @brief L2归一化处理
             * @param input 输入特征数据
             * @param size_ 特征数据大小
             * @return 归一化后的结果
             */
            double reduceL2(const float* input, int size_);

            /**
             * @brief 运行模型推理
             * @param working_img 输入图像Tensor
             * @param out 输出特征向量
             */
            void run_model(magik::uranus::Tensor &working_img,std::vector<float> &out);

            /**
             * @brief 计算两个特征向量的L2距离
             * @param a 特征向量a
             * @param b 特征向量b
             * @return 距离值
             */
            float L2_distance(const std::vector<float>& a, const std::vector<float>& b);

        public:
            /**
             * @brief 构造函数
             * @param recog_config 识别配置参数
             */
            RecogInterface(RecogConfig recog_config);

            /**
             * @brief 加载识别模型
             * @return 0表示成功，非0表示失败
             */
            int loadModel();

            /**
             * @brief 释放模型资源
             * @return 0表示成功，非0表示失败
             */
            int releaseModel();

            /**
             * @brief 打印模型前向传播内存使用情况
             */
            void print_model_forward_memory();

            /**
             * @brief 注册猫只信息
             * @param recog_working_img 猫脸图像Tensor
             * @param register_info 注册信息结构体引用
             * @param name 猫只名称
             * @param id 猫只唯一标识ID
             */
            void registerCat(magik::uranus::Tensor &recog_working_img, RegisterInfo &register_info, std::string name, std::string id);

            /**
             * @brief 打印注册信息列表
             * @param register_infos 注册信息列表引用
             */
            void printRegisterInfo(std::vector<RegisterInfo> &register_infos);

            /**
             * @brief 执行猫脸识别
             * @param recog_working_img 待识别猫脸图像Tensor
             * @param recognize_info 识别结果信息列表引用
             * @param register_infos 已注册猫只信息列表引用
             */
            void recognizeCat(magik::uranus::Tensor &recog_working_img, std::vector<RecognizeInfo> &recognize_info, std::vector<RegisterInfo> &register_infos);

            /**
             * @brief 打印识别结果
             * @param recognize_results 识别结果列表引用
             */
            void printRecognizeResults(std::vector<RecognizeInfo> &recognize_results);
    };
};
#endif